package com.dal.rpc.core.common;

import com.dal.rpc.core.enums.PackageType;
import com.dal.rpc.core.serializer.Serializer;
import com.dal.rpc.core.serializer.kryo.KryoSerializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.log4j.Log4j2;


import java.util.List;

/**
 * @program: dal-springboot
 * @description: netty解码器
 * @author: jian
 * @create: 2021-11-17 14:47
 */
@Log4j2
public class NettyDecoder extends ByteToMessageDecoder {

    private static final int MAGIC_NUMBER = 0xCAFEBABE;

    /*private Class<?> genericClass;
    private Serializer serialize;

    *//**
     * 构造函数传入向反序列化的class
     * @param genericClass
     *//*
    public NettyDecoder(Class<?> genericClass,Serializer serialize) {
        this.genericClass = genericClass;
        this.serialize = serialize;
    }*/

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        //读取魔数,判断
        int magic = in.readInt();
        if(magic != MAGIC_NUMBER) {
            log.error("不识别的协议包: {}", magic);
            //throw new RpcException(RpcError.UNKNOWN_PROTOCOL);
        }
        int packageCode = in.readInt();
        Class<?> packageClass = null;
        if(packageCode == PackageType.REQUEST_PACK.getCode()) {
            packageClass = RpcRequest.class;
        } else if(packageCode == PackageType.RESPONSE_PACK.getCode()) {
            packageClass = RpcResponse.class;
        } else {
            log.error("不识别的数据包: {}", packageCode);
            //throw new RpcException(RpcError.UNKNOWN_PACKAGE_TYPE);
        }
        int serializerCode = in.readInt();

        Serializer serializer = Serializer.getByCode(serializerCode);

        if(serializer == null) {
            log.error("不识别的反序列化器: {}", serializerCode);
            //throw new RpcException(RpcError.UNKNOWN_SERIALIZER);
        }
        int length = in.readInt();
        byte[] bytes = new byte[length];
        in.readBytes(bytes);
        Object obj = serializer.deserialize(bytes, packageClass);
        out.add(obj);

        /*if (in.readableBytes() < 4) {
            return;
        }
        in.markReaderIndex();
        int dataLength = in.readInt();
        if (dataLength < 0) {
            ctx.close();
        }
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[] data = new byte[dataLength];
        in.readBytes(data);

        Object object = serialize.deserialize(data, genericClass);
        out.add(object);*/

    }
}
